﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;
using System.ComponentModel;

namespace CMDBImportCIDLL
{
    public class MapModelByXML<T>
    {
        static public List<T> MapExcelDataToModelByXML(DataTable dt, Sheet sheet)
        {
            dt = (new MapModelByXML<T>()).SpecialColumn(dt, sheet);
            List<T> result = new List<T>();

            CommonExcelOperate ceo = new CommonExcelOperate();
        
            for (int i = 1; i < dt.Rows.Count; i++)
            {
                T obj = Activator.CreateInstance<T>();
                foreach (var item in sheet.ColumnList)
                {

                    PropertyInfo pi = obj.GetType().GetProperty(item.DBName, BindingFlags.Instance | BindingFlags.Public);

                    if (pi == null)
                    {
                        throw new Exception("XML映射数据库字段出错，请检查Excel.xml文件！");
                    }
                    string value = dt.Rows[i][item.ColumnId].ToString();
                    try
                    {
                        if (pi.PropertyType.Name.Contains("Nullable"))
                        {
                            NullableConverter converter = new NullableConverter(pi.PropertyType);
                            if (string.IsNullOrEmpty(value))
                            {
                                pi.SetValue(obj, null, null);
                            }
                            else
                            {
                                pi.SetValue(obj, converter.ConvertFromString(value), null);
                            }
                        }
                        else
                        {
                            pi.SetValue(obj, Convert.ChangeType(value, pi.PropertyType), null);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(string.Format("Excel中 ${0}$ Sheet页的第 {1} 行 {2} 列无法转化为 {3} 类型: {4}", sheet.SheetName, i, item.ColumnId, pi.PropertyType, ex.Message));
                    }

                }
                //三层
                PropertyInfo picate = obj.GetType().GetProperty("Category", BindingFlags.Instance | BindingFlags.Public);
                if (picate != null)
                {
                    picate.SetValue(obj, Convert.ChangeType(sheet.Category, picate.PropertyType), null);
                }
                PropertyInfo pitype = obj.GetType().GetProperty("Type", BindingFlags.Instance | BindingFlags.Public);
                if (pitype != null)
                {
                    pitype.SetValue(obj, Convert.ChangeType(sheet.Type, pitype.PropertyType), null);
                }
                PropertyInfo piitem = obj.GetType().GetProperty("Item", BindingFlags.Instance | BindingFlags.Public);
                if (piitem != null)
                {
                    piitem.SetValue(obj, Convert.ChangeType(sheet.Item, piitem.PropertyType), null);
                }

                result.Add(obj);
            }
            return result;

        }

        private DataTable SpecialColumn(DataTable dt, Sheet sheet)
        {
            if (sheet.SheetName == "服务器")
            {
                foreach (var item in sheet.ColumnList)
                {
                    if (item.DBName == "IsVirtual")
                    {
                        for (int i = 1; i < dt.Rows.Count; i++)
                        {
                            string value = dt.Rows[i][item.ColumnId].ToString().ToLower();
                            if (value == "y" || value == "yes" || value == "是" || value == "1")
                            {
                                dt.Rows[i][item.ColumnId] = "1";
                            }
                            else
                            {
                                dt.Rows[i][item.ColumnId] = "0";
                            }
                        }
                    }
                }
            }
            return dt;
        }



    }
}
